2bb8434e3054ceaecfd50515f40a3ce1608c73c4,src/net/spfbl/spf/SPF.java,SPF,processSPF,#String#String#,3679

Before Change


                                return "FAIL\n";
                            } else if (sender != null && !Domain.isEmail(sender)) {
                                String ticket = SPF.addQuery(tokenSet);
                                CacheComplain.addComplain(client, ticket);
                                return "INVALID\n";
                            } else if (sender != null && Domain.isReserved(sender)) {
                                String ticket = SPF.addQuery(tokenSet);
                                CacheComplain.addComplain(client, ticket);
                                return "INVALID\n";
                            } else if (sender == null && !CacheHELO.match(ip, hostname)) {
                                String ticket = SPF.addQuery(tokenSet);
                                CacheComplain.addComplain(client, ticket);
                                // HELO inválido sem remetente.
                                return "INVALID\n";
                            } else if (hostname == null && Core.isReverseRequired()) {
                                String ticket = SPF.addQuery(tokenSet);
                                CacheComplain.addComplain(client, ticket);
                                if (Block.tryAdd(ip)) {
                                    Server.logDebug("new BLOCK '" + ip + "' added by 'ReverseRequired'.");
                                }
                                // Require a valid HELO or reverse.
                                return "INVALID\n";
                            } else if (Trap.contains(client, recipient)) {
                                // Calcula frequencia de consultas.
                                String ticket = SPF.addQuery(tokenSet);
                                CacheComplain.addComplain(client, ticket);
                                return "SPAMTRAP\n";
                            } else if (Defer.count(fluxo) > Core.getFloodMaxRetry()) {
                                // A origem atingiu o limite de atraso 

After Change


                return "ERROR: QUERY\n";
            } else {
                String origin;
                if (client == null) {
                    origin = ipAddress.getHostAddress();
                } else if (client.hasEmail()) {
                    origin = ipAddress.getHostAddress() + " " + client.getDomain() + " " + client.getEmail();
                } else {
                    origin = ipAddress.getHostAddress() + " " + client.getDomain();
                }
                StringTokenizer tokenizer = new StringTokenizer(query, " ");
                String firstToken = tokenizer.nextToken();
                if (firstToken.equals("SPAM") && tokenizer.countTokens() == 1) {
                    String ticket = tokenizer.nextToken();
                    TreeSet<String> tokenSet = CacheComplain.addComplain(origin, ticket);
                    if (tokenSet == null) {
                        result = "DUPLICATE COMPLAIN\n";
                    } else {
                        String recipient = SPF.getRecipient(ticket);
                        result = "OK " + tokenSet + (recipient == null ? "" : " >" + recipient) + "\n";
                    }
                } else if (firstToken.equals("HAM") && tokenizer.countTokens() == 1) {
                    String ticket = tokenizer.nextToken();
                    TreeSet<String> tokenSet = CacheComplain.deleteComplain(origin, ticket);
                    if (tokenSet == null) {
                        result = "ALREADY REMOVED\n";
                    } else {
                        String recipient = SPF.getRecipient(ticket);
                        result = "OK " + tokenSet + (recipient == null ? "" : " >" + recipient) + "\n";
                    }
                } else if (firstToken.equals("REFRESH") && tokenizer.countTokens() == 1) {
                    String address = tokenizer.nextToken();
                    try {
                        if (CacheSPF.refresh(address, true)) {
                            result = "UPDATED\n";
                        } else {
                            result = "NOT LOADED\n";
                        }
                    } catch (ProcessException ex) {
                        result = ex.getMessage() + "\n";
                    }
                } else if ((firstToken.equals("SPF") && tokenizer.countTokens() >= 4)
                        || tokenizer.countTokens() == 2 || tokenizer.countTokens() == 1
                        || (firstToken.equals("CHECK") && tokenizer.countTokens() == 4)
                        || (firstToken.equals("CHECK") && tokenizer.countTokens() == 3)
                        || (firstToken.equals("CHECK") && tokenizer.countTokens() == 2)) {
                    try {
                        String ip;
                        String sender;
                        String helo;
                        String recipient;
                        String origem;
                        String fluxo;
                        if (firstToken.equals("SPF")) {
                            // Nova formatação de consulta.
                            ip = tokenizer.nextToken();
                            sender = tokenizer.nextToken();
                            while (!sender.endsWith("'") && tokenizer.hasMoreTokens()) {
                                sender += " " + tokenizer.nextToken();
                            }
                            helo = tokenizer.hasMoreTokens() ? tokenizer.nextToken() : "''";
                            recipient = tokenizer.hasMoreTokens() ? tokenizer.nextToken() : "''";
                            ip = ip.substring(1, ip.length() - 1);
                            sender = sender.substring(1, sender.length() - 1);
                            helo = helo.substring(1, helo.length() - 1);
                            recipient = recipient.substring(1, recipient.length() - 1);
                            if (sender.length() == 0) {
                                sender = null;
                            } else {
                                sender = sender.toLowerCase();
                            }
                            if (!Domain.isEmail(recipient)) {
                                recipient = null;
                            }
                        } else if (firstToken.equals("CHECK") && tokenizer.countTokens() == 4) {
                            ip = tokenizer.nextToken().toLowerCase();
                            sender = tokenizer.nextToken().toLowerCase();
                            helo = tokenizer.nextToken().toLowerCase();
                            recipient = tokenizer.nextToken().toLowerCase();
                            if (ip.startsWith("'") && ip.endsWith("'")) {
                                ip = ip.substring(1, ip.length() - 1);
                            }
                            if (sender.startsWith("'") && sender.endsWith("'")) {
                                sender = sender.substring(1, sender.length() - 1);
                            }
                            if (helo.startsWith("'") && helo.endsWith("'")) {
                                helo = helo.substring(1, helo.length() - 1);
                            }
                            if (recipient.startsWith("'") && recipient.endsWith("'")) {
                                recipient = recipient.substring(1, recipient.length() - 1);
                            }
                            if (ip.length() == 0) {
                                ip = null;
                            }
                            if (sender.length() == 0) {
                                sender = null;
                            }
                            if (helo.length() == 0) {
                                helo = null;
                            }
                            if (recipient.length() == 0) {
                                recipient = null;
                            }
                        } else {
                            // Manter compatibilidade da versão antiga.
                            // Versão obsoleta.
                            if (firstToken.equals("CHECK")) {
                                ip = tokenizer.nextToken();
                            } else {
                                ip = firstToken;
                            }
                            if (tokenizer.countTokens() == 2) {
                                sender = tokenizer.nextToken().toLowerCase();
                                helo = tokenizer.nextToken().toLowerCase();
                            } else {
                                sender = null;
                                helo = tokenizer.nextToken().toLowerCase();
                            }
                            recipient = null;
                            if (ip.startsWith("'") && ip.endsWith("'")) {
                                ip = ip.substring(1, ip.length() - 1);
                            }
                            if (sender != null && sender.startsWith("'") && sender.endsWith("'")) {
                                sender = sender.substring(1, sender.length() - 1);
                                if (sender.length() == 0) {
                                    sender = null;
                                }
                            }
                            if (helo.startsWith("'") && helo.endsWith("'")) {
                                helo = helo.substring(1, helo.length() - 1);
                            }
                        }
                        if (!Subnet.isValidIP(ip)) {
                            return "INVALID\n";
                        } else if (
                                Subnet.containsIP("10.0.0.0/8", ip) ||
                                Subnet.containsIP("172.16.0.0/12", ip) ||
                                Subnet.containsIP("192.168.0.0/16", ip) ||
                                Subnet.containsIP("169.254.0.0/16", ip)
                                ) {
                            // Message from LAN.
                            return "LAN\n";
                        } else {
                            TreeSet<String> tokenSet = new TreeSet<String>();
                            ip = Subnet.normalizeIP(ip);
                            tokenSet.add(ip);
                            if (client != null && client.hasEmail()) {
                                // Se houver um cliente válido,
                                // Adicionar no ticket para controle.
                                tokenSet.add(client.getEmail() + ':');
                            }
                            if (Domain.isEmail(recipient)) {
                                // Se houver um remetente válido,
                                // Adicionar no ticket para controle.
                                tokenSet.add('>' + recipient);
                            } else {
                                recipient = null;
                            }
                            
                            // Passar a acompanhar todos os 
                            // HELO quando apontados para o IP para 
                            // uma nova forma de interpretar dados.
                            String hostname;
                            if (CacheHELO.match(ip, helo)) {
                                helo = Domain.normalizeHostname(helo, true);
                                hostname = helo;
                            } else {
                                hostname = Reverse.getHostname(ip);
                                hostname = Domain.normalizeHostname(hostname, true);
                            }
                            if (hostname == null) {
                                Server.logDebug("no reverse for " + ip + ".");
                            } else {
                                tokenSet.add(hostname);
                                String ipv4 = CacheHELO.getUniqueIPv4(hostname);
                                if (ipv4 != null) {
                                    // Equivalência de pilha dupla se 
                                    // IPv4 for único para o hostname.
                                    tokenSet.add(ipv4);
                                }
                                String ipv6 = CacheHELO.getUniqueIPv6(hostname);
                                if (ipv6 != null) {
                                    // Equivalência de pilha dupla se 
                                    // IPv6 for único para o hostname.
                                    tokenSet.add(ipv6);
                                }
                            }
                            LinkedList<String> logList = null;
                            if (sender != null && firstToken.equals("CHECK")) {
                                int index = sender.lastIndexOf('@');
                                String domain = sender.substring(index + 1);
                                logList = new LinkedList<String>();
                                try {
                                    CacheSPF.refresh(domain, false);
                                } catch (ProcessException ex) {
                                    logList.add("Cannot refresh SPF registry: " + ex.getErrorMessage());
                                    logList.add("Using cached SPF registry.");
                                }
                            }
                            SPF spf;
                            if (sender == null) {
                                spf = null;
                                result = "NONE";
                            } else if (!Domain.isEmail(sender)) {
                                spf = null;
                                result = "NONE";
                            } else if (Domain.isReserved(sender)) {
                                spf = null;
                                result = "NONE";
                            } else if ((spf = CacheSPF.get(sender)) == null) {
                                result = "NONE";
                            } else if (spf.isInexistent()) {
                                result = "NONE";
                            } else {
                                result = spf.getResult(ip, sender, helo, logList);
                            }
                            if (result.equals("PASS") || (sender != null && Provider.containsHELO(ip, hostname))) {
                                // Quando fo PASS, significa que o domínio
                                // autorizou envio pelo IP, portanto o dono dele
                                // é responsavel pelas mensagens.
                                String mx = Domain.extractHost(sender, true);
                                if (Provider.containsExact(mx)) {
                                    // Listar apenas o remetente se o
                                    // hostname for um provedor de e-mail.
                                    tokenSet.add(sender);
                                    origem = sender;
                                } else {
                                    // Não é um provedor então
                                    // o MX deve ser listado.
                                    tokenSet.add(mx);
                                    origem = mx;
                                }
                                fluxo = origem + ">" + recipient;
                            } else if (hostname == null) {
                                origem = (sender == null ? "" : sender + '>') + ip;
                                fluxo = origem + ">" + recipient;
                                hostname = helo;
                            } else {
                                String dominio = Domain.extractDomain(hostname, true);
                                origem = (sender == null ? "" : sender + '>') + (dominio == null ? hostname : dominio.substring(1));
                                fluxo = origem + ">" + recipient;
                            }
                            if (firstToken.equals("CHECK")) {
                                String results = "\nSPF resolution results:\n";
                                if (logList == null || logList.isEmpty()) {
                                    results += "   NONE\n";
                                } else {
                                    for (String log : logList) {
                                        results += "   " + log + "\n";
                                    }
                                }
                                String white = White.find(client, ip, sender, hostname, result, recipient);
                                if (white != null) {
                                    results += "\nFirst WHITE match: " + white + "\n";
                                }
                                String block = Block.find(client, ip, sender, hostname, result, recipient);
                                if (block != null) {
                                    results += "\nFirst BLOCK match: " + block + "\n";
                                }
                                results += "\n";
                                results += "Considered identifiers and status:\n";
                                tokenSet = expandTokenSet(tokenSet);
                                TreeMap<String,Distribution> distributionMap = CacheDistribution.getMap(tokenSet);
                                for (String token : tokenSet) {
                                    if (!token.startsWith(">") && !token.endsWith(":")) {
                                        float probability;
                                        Status status;
                                        if (distributionMap.containsKey(token)) {
                                            Distribution distribution = distributionMap.get(token);
                                            probability = distribution.getSpamProbability(token);
                                            status = distribution.getStatus(token);
                                        } else {
                                            probability = 0.0f;
                                            status = SPF.Status.WHITE;
                                        }
                                        results += "   " + token
                                                + " " + status.name() + " "
                                                + Server.DECIMAL_FORMAT.format(probability) + "\n";
                                    }
                                }
                                results += "\n";
                                return results;
                            } else if (White.contains(client, ip, sender, hostname, result, recipient)) {
//                                if (result.equals("PASS") && White.containsExact(client + ':' + origem + ";PASS>" + recipient)) {
//                                    // Limpa da lista BLOCK um possível falso positivo.
//                                    Block.clear(null, ip, sender, hostname, result, null);
//                                } else
                                if (White.contains(client, ip, sender, hostname, result, null)) {
//                                  // Limpa da lista BLOCK um possível falso positivo.
                                    Block.clear(null, ip, sender, hostname, result, null);
                                }
                                // Calcula frequencia de consultas.
                                String url = Core.getSpamURL(recipient);
                                String ticket = SPF.addQuery(tokenSet);
                                return result + " " + (url == null ? ticket : url + URLEncoder.encode(ticket, "UTF-8")) + "\n";
                            } else if (Block.contains(client, ip, sender, hostname, result, recipient)) {
                                // Calcula frequencia de consultas.
                                String ticket = SPF.addQuery(tokenSet);
                                CacheComplain.addComplain(origin, ticket);
                                String url = Core.getUnblockURL(client, ip, sender, hostname, result, recipient);
                                if (url == null) {
                                    return "BLOCKED\n";
                                } else {
                                    return "BLOCKED " + url + "\n";
                                }
                            } else if (spf != null && spf.isDefinitelyInexistent()) {
                                // O domínio foi dado como inexistente inúmeras vezes.
                                // Rejeitar e denunciar o host pois há abuso de tentativas.
                                String ticket = SPF.addQuery(tokenSet);
                                CacheComplain.addComplain(origin, ticket);
                                return "NXDOMAIN\n";
                            } else if (spf != null && spf.isInexistent()) {
                                return "NXDOMAIN\n";
                            } else if (result.equals("FAIL")) {
                                String ticket = SPF.addQuery(tokenSet);
                                CacheComplain.addComplain(origin, ticket);
                                // Retornar FAIL somente se não houver 
                                // liberação literal do remetente com FAIL.
                                return "FAIL\n";
                            } else if (sender != null && !Domain.isEmail(sender)) {
                                String ticket = SPF.addQuery(tokenSet);
                                CacheComplain.addComplain(origin, ticket);
                                return "INVALID\n";
                            } else if (sender != null && Domain.isReserved(sender)) {
                                String ticket = SPF.addQuery(tokenSet);
                                CacheComplain.addComplain(origin, ticket);
                                return "INVALID\n";
                            } else if (sender == null && !CacheHELO.match(ip, hostname)) {
                                String ticket = SPF.addQuery(tokenSet);
                                CacheComplain.addComplain(origin, ticket);
                                // HELO inválido sem remetente.
                                return "INVALID\n";
                            } else if (hostname == null && Core.isReverseRequired()) {